<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html><head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Testing with Paste and Nose (web.py)</title> 
  <link rel="stylesheet" type="text/css" href="/static/webpy-new.css"/> 
  <link rel="SHORTCUT ICON" href="/static/favicon.ico"/> 
</head><body> 
 
        <div id="header"><table class="header"><tr>
                <td class="logo"><a href="/" title="Home"><img src="/static/webpy.gif" alt="" /></a></td> 
<td class="blurb">&ldquo;Think about the ideal way to write a web app.<br />Write the code to make it happen.&rdquo; [<a href="/philosophy">more...</a>]</td> </tr>
</table>
        </div> 
        <div id="location"> 
                <a href="/">home</a> &gt; Testing with Paste and Nose
        </div> 
<div id="container"> 
<div id="sidebar">
<strong>get started:</strong>
<ul class="body">
  <li><a href="/install">install</a></li>
  <li><a href="/docs/0.3/tutorial">tutorial</a></li>
</ul>
<strong>learn more:</strong>
<ul class="body">
<li><a href="/docs/0.3/api">api reference</a></li>
<li><a href="/cookbook/">cookbook</a></li>
<li><a href="/src/">code examples</a></li>
</ul>

<strong>dive in:</strong>
<ul class="body"> 
<li><a href="https://github.com/webpy/webpy">source code</a></li>
<li><a href="http://groups.google.com/group/webpy/">mailing list</a></li>
<li><a href="https://github.com/webpy/webpy/issues">issue tracker</a></li>
</ul>
</div>

<div id="main"> 
<div id="content" class="body"> 
<h1>Testing with Paste and Nose</h1>

<h2>Problem</h2>

<p>You want to test your web.py application.</p>

<h2>Solution</h2>

<pre><code>from paste.fixture import TestApp
from nose.tools import *
from code import app

class TestCode():
    def test_index(self):
        middleware = []
        app = TestApp(app.wsgifunc(*middleware))
        r = app.get('/')
        assert_equal(r.status, 200)
        r.mustcontain('Hello, world!')
</code></pre>

<h2>Background</h2>

<p>This example makes use of the Paste and Nose libraries. <a href="http://pythonpaste.org/">Paste</a> lets you throw test requests at your application, and adds some helpful <a href="http://pythonpaste.org/webtest/#the-response-object">custom methods to the response objects</a>, such as mustcontain(), seen above. <a href="http://somethingaboutorange.com/mrl/projects/nose/">Nose</a> makes writing and running your tests dead simple. When run from the base of your tree, it automatically finds and runs anything which is named like a test, adding necessary modules to your PYTHONPATH. This gives you the flexibility to run your tests from other directories, as well. Another benefit of Nose is that you no longer need to have every test class inherit from unittest.TestCase. Many more details are outlined on the project page.</p>

<h2>Explanation</h2>

<p>This code resides in a file called test_code.py. The directory layout of the application looks like this:</p>

<pre><code>./
code.py
./test
    test_code.py        
</code></pre>

<p>Most of the code example above should be fairly self-explanatory. From our main module, code, we import app, which is defined in the usual way:</p>

<pre><code>app = web.application(urls, globals())
</code></pre>

<p>To set up the test, we pass its wsgifunc() to Paste's TestApp, as you have already seen in the example.</p>

<pre><code>app = TestApp(app.wsgifunc(*middleware))
</code></pre>

<p>assert_equal() is one of the methods provided by nose's utils, and works just like unittest's assertEqual().</p>

<h2>Setting Up the Test Environment</h2>

<p>In order to avoid kicking off web.py's webserver when we run our tests, a change is required to the line which calls run(). It normally looks something like this:</p>

<pre><code>if __name__ == "__main__": app.run()
</code></pre>

<p>We can define an environment variable, such as WEBPY_ENV=test, when we run our tests. In that case, the above line becomes the following:</p>

<pre><code>import os

def is_test():
    if 'WEBPY_ENV' in os.environ:
        return os.environ['WEBPY_ENV'] == 'test'

if (not is_test()) and __name__ == "__main__": app.run()
</code></pre>

<p>Then, it's simply a matter of running nosetests like so:</p>

<pre><code>WEBPY_ENV=test nosetests
</code></pre>

<p>The is_test() function comes in handy for other things, such as doing conditional database commits to avoid test database pollution.</p>

<div style="clear: both;"></div> 
 
</div> 
 
</div> 
</div>
        <div id="footer"> 
    <p>started by <a style="color: gray;" href="http://www.aaronsw.com/">Aaron Swartz</a> (<a style="color: black;" href="mailto:webpy@aaronsw.com">webpy@aaronsw.com</a>)</p>

<p><a href="https://github.com/webpy/webpy.github.com/blob/master/cookbook/testing_with_paste_and_nose.zh-cn.md">fork this page on GitHub</a></p>
</div> 
 
</body> 
</html> 
